#ifndef __PLAYER_MODEL_H_
#define __PLAYER_MODEL_H_

#include <Ogre.h>
#include <map>
#include "PapaObject.h"
#include "BoneData.h"
#include "XnTypes.h"
#include "Kinect.h"

using namespace Ogre;
typedef std::map<int,Ogre::Bone> BoneDataType;

#define NUM_ANIMS 13           // number of animations the character has
#define CHAR_HEIGHT 5          // height of character's center of mass above ground
#define CAM_HEIGHT 2           // height of camera above character's center of mass
#define RUN_SPEED 17           // character running speed in units per second
#define TURN_SPEED 500.0f      // character turning in degrees per second
#define ANIM_FADE_SPEED 7.5f   // animation crossfade speed in % of full weight per second
#define JUMP_ACCEL 30.0f       // character jump acceleration in upward units per squared second
#define GRAVITY 90.0f          // GRAVITY in downward units per squared second

#define BONE_ANMI 0
#define BONE_KINECT 1
extern const Ogre::String BoneNames[];
class PlayerModel:public PapaObject
{
public:
	enum AnimID
	{
		ANIM_IDLE_BASE,
		ANIM_IDLE_TOP,
		ANIM_RUN_BASE,
		ANIM_RUN_TOP,
		ANIM_HANDS_CLOSED,
		ANIM_HANDS_RELAXED,
		ANIM_DRAW_SWORDS,
		ANIM_SLICE_VERTICAL,
		ANIM_SLICE_HORIZONTAL,
		ANIM_DANCE,
		ANIM_JUMP_START,
		ANIM_JUMP_LOOP,
		ANIM_JUMP_END,
		ANIM_NONE
	};
private://field
	//View Model Data
	BoneData bones[11];
	Entity *mBodyEnt;
	SceneNode* mBodyNode;
	

	//Animation Data
	AnimID currentAnimID;
	AnimID nextAnimID;
	bool m_bBoneAnimationEnable;
	Ogre::AnimationState* mAnims[NUM_ANIMS];    // master animation list
	AnimID mBaseAnimID;                   // current base (full- or lower-body) animation
	AnimID mTopAnimID;                    // current top (upper-body) animation
	bool mFadingIn[NUM_ANIMS];            // which animations are fading in
	bool mFadingOut[NUM_ANIMS];           // which animations are fading out
	Real mTimer; 

	//sword
	bool mSwordsDrawn;
	Entity* mSword1;
	Entity* mSword2;
	RibbonTrail* mSwordTrail;

	//View
	SceneManager *mSceneMgr;
	
	std::map<Ogre::String,Ogre::Quaternion> _keyOrientation;
	std::map<Ogre::String,Ogre::Quaternion> _kinectOrientation;

public://cons&destroy
	PlayerModel(Ogre::SceneManager *sceneMgr,AnimID BaseAnimationID=AnimID::ANIM_IDLE_BASE);
	~PlayerModel();

public://attribute
	void setBoneData();
	BoneData* getBoneData();
	void transformBone(const Ogre::String& modelBoneName, XnSkeletonJoint skelJoint, bool flip);
	void resetBonesToInitialState();
	double m_SmoothingFactor;
	int m_SmoothingDelta;
	bool m_front;	
	bool suppress;
	Ogre::Vector3 m_origTorsoPos;
	void setJumpAnimation();

	void setTopAnimation(AnimID anim,bool strictReset=false);
	AnimID getTopAnimation();

	void setBaseAnimation(AnimID anim,bool strictReset=false);
	AnimID getBaseAnimation();

	void setBoneDataMode(int i);
public://method
	void setBoneAnimationEnable(Ogre::String BoneNames[],bool state,int size);
	void AddTime(Ogre::Real deltaTime);
	void Initialization();
public://data
	AnimID getBaseAnimID(){ return mBaseAnimID; }
	AnimID getTopAnimID(){ return mTopAnimID; }

public: //game logic
	void Hurt(){};
public: //game property

protected://help method
	void updateAnimations(Real deltaTime);
	void fadeAnimations(Real deltaTime);
	void setupBone(std::map<Ogre::String,Ogre::Quaternion>& initial);
	void setupBone(const String& name,const Ogre::Quaternion& q);
	void setupBone(const String& name,const Ogre::Radian& angle, const Ogre::Vector3 axis);
	void setupBone(const String& name,const Degree& yaw,const Degree& pitch,const Degree& roll);

public:
	
};
#endif